package com.taokatao.cardmee.business.cardcrud;

import android.content.Intent;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SectionIndexer;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.google.gson.reflect.TypeToken;
import com.jakewharton.rxbinding.widget.RxTextView;
import com.taokatao.cardmee.App;
import com.taokatao.cardmee.BaseActivity;
import com.taokatao.cardmee.C;
import com.taokatao.cardmee.R;
import com.taokatao.cardmee.Utils;
import com.taokatao.cardmee.api.ApiManager;
import com.taokatao.cardmee.api.RespWrapper;
import com.taokatao.cardmee.api.SubscriberAdapter;
import com.taokatao.cardmee.common.widget.TitleLayout;
import com.taokatao.cardmee.common.widget.stickylist.ExpandableStickyListHeadersListView;
import com.taokatao.cardmee.common.widget.stickylist.StickyListHeadersAdapter;
import com.taokatao.cardmee.db.CardGradeDao;
import com.taokatao.cardmee.db.CardStoreDao;
import com.taokatao.cardmee.db.model.CardGrade;
import com.taokatao.cardmee.db.model.CardStore;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnFocusChange;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

public class CardSearchActivity extends BaseActivity implements View.OnClickListener, View.OnFocusChangeListener, TitleLayout.Callback {

    @BindView(R.id.l_title) TitleLayout layTitle;
    @BindView(R.id.v_sticky_list) ExpandableStickyListHeadersListView listSticky;
    @BindView(R.id.v_side) SideBar vSlide;
    private List<CardStore> dataSimpleList = new ArrayList<>();
    private CardStoreAdapter adapter;

    @BindView(R.id.v_search_list) ListView listSearch;
    private List<CardStore> dataList;
    private CardStoreAfterSearchedAdapter adapterAfterSearched;
    @BindView(R.id.i_load) ImageView iLoad;
    @BindView(R.id.e_search) EditText eSearch;
    @BindView(R.id.i_clear) ImageView iClear;
    @BindView(R.id.t_empty) View tEmpty;
    @BindView(R.id.t_close) View tClose;
    View lAddOther;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        isSupportTouchBack = false;
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_card_search);
        ButterKnife.bind(this);

        layTitle.setCallback(this);


        lAddOther = LayoutInflater.from(this).inflate(R.layout.recycler_card_search_content, null);
        lAddOther.setOnClickListener(this);
        TextView tName = (TextView) lAddOther.findViewById(R.id.t_name);
        tName.getPaint().setFakeBoldText(true);
        tName.setText("添加其它卡");
        ImageView iIcon = (ImageView) lAddOther.findViewById(R.id.i_icon);
        iIcon.setImageResource(R.mipmap.card_add_other);
        listSticky.addHeaderView(lAddOther);

        final View.OnTouchListener inputHideCallback = new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                Utils.hideSoftInputFromWindowAlways(CardSearchActivity.this);
                eSearch.clearFocus();
                return false;
            }
        };
        listSticky.setOnTouchListener(inputHideCallback);
        listSearch.setOnTouchListener(inputHideCallback);
        listSticky.setAdapter(adapter = new CardStoreAdapter());
        listSearch.setAdapter(adapterAfterSearched = new CardStoreAfterSearchedAdapter());
        vSlide.setVisibility(View.GONE);
        vSlide.setOnTouchingLetterChangedListener(new SideBar.OnTouchingLetterChangedListener() {
            @Override
            public void onTouchingLetterChanged(String s) {
                int position = adapter.getPositionForSection(s.charAt(0));
                if (position != -1) {
                    listSticky.setSelection(position + 1);
                }
            }
        });

        RxTextView.textChanges(eSearch).doOnNext(new Action1<CharSequence>() {
            @Override
            public void call(final CharSequence charSequence) {
                Utils.logd("RxTextView.textChanges(eSearch)[thread:%d]", Thread.currentThread().getId());
                if (!TextUtils.isEmpty(charSequence)) {
                    iLoad.setVisibility(View.VISIBLE);
                    ((AnimationDrawable) iLoad.getBackground()).start();
                    iClear.setVisibility(View.GONE);
                }
            }
        }).debounce(C.settings.ANIMATION_TIME, TimeUnit.MILLISECONDS)
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(Schedulers.computation())
                .map(new Func1<CharSequence, List<CardStore>>() {
                    @Override
                    public List<CardStore> call(CharSequence s) {
                        if (TextUtils.isEmpty(s) || dataList == null) return null;

                        String lowerSearch = s.toString().replaceAll(" ", "").toLowerCase();
                        List<CardStore> filterResult = new ArrayList<>();
                        for (CardStore cs : dataList) {
                            String lowerSearchKeys = cs.getSearchKeys().toLowerCase();
                            if (lowerSearchKeys.contains(lowerSearch)) {
                                filterResult.add(cs);
                            }
                        }
                        return filterResult;
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<List<CardStore>>() {
                    @Override
                    public void call(List<CardStore> filterResult) {
                        iLoad.setVisibility(View.GONE);
                        ((AnimationDrawable) iLoad.getBackground()).stop();

                        if (!TextUtils.isEmpty(eSearch.getText())) {
                            iClear.setVisibility(View.VISIBLE);
                        }

                        if (filterResult == null) filterResult = new ArrayList<>();
                        adapterAfterSearched.setData(filterResult);

                        if (View.VISIBLE == listSearch.getVisibility()) {
                            tEmpty.setVisibility(filterResult.size() < 1 && !TextUtils.isEmpty(eSearch.getText()) ? View.VISIBLE : View.GONE);
                        }
                    }
                });

        prepareDataByDBQuery();
        requestQueryCardStore();
    }

    private void prepareDataByDBQuery() {
        CardStoreDao cardStoreDao = App.i().getCommonDBSession().getCardStoreDao();
        List<CardStore> cardStoreList = cardStoreDao.queryBuilder().where(CardStoreDao.Properties.SearchKeys.isNotNull(),
                CardStoreDao.Properties.BusinessId.notEq(C.settings.BUSINESS_OTHER_ID)).orderAsc(CardStoreDao.Properties.Sort)
                .orderDesc(CardStoreDao.Properties.UseCount)
                .orderAsc(CardStoreDao.Properties.BusinessName).list();
        List<String> sortList = new ArrayList<>();

        dataSimpleList.clear();
        boolean isContainsHot = false;
        for (CardStore cs : cardStoreList) {
            String mSort = cs.getSort();
            if (!TextUtils.isEmpty(mSort) && mSort.length() == 1) {
                if (cs.getIfHot() != null && CardStore.STATUS_HOT == cs.getIfHot()) {
                    isContainsHot = true;
                }
                if (!sortList.contains(mSort)) {
                    sortList.add(mSort);
                }
            }

            if (cs.getRegionId() != null && CardStore.REGION_CHINA == cs.getRegionId().intValue()) {
                dataSimpleList.add(cs);
            }
        }
        if (isContainsHot) {
            sortList.add(0, "热");
        }
        // 用于搜索
        dataList = cardStoreList;
        // 简要版只显示[regionId == 1]
        adapter.setData(dataSimpleList);
        vSlide.setIndexText(sortList);
        vSlide.setVisibility(sortList.size() > 0 ? View.VISIBLE : View.GONE);
    }

    /**
     * 同步商家数据
     */
    private void requestQueryCardStore() {
        if (App.DEBUG_LOG) {
            CardStoreDao cardStoreDao = App.i().getCommonDBSession().getCardStoreDao();
            long cardStoreTotalCount = cardStoreDao.queryBuilder().count();
            Utils.logd("requestQueryCardStore cardStoreTotalCount [%d]", cardStoreTotalCount);
        }

        if (App.DEBUG_SERVICE) {
            return;// 测试服务器不同步商家数据
        }

        final boolean isNeedUpdateLocalData = false;

        long syncStartTime = isNeedUpdateLocalData ? 20090909090909l : Utils.spReadLong("api_queryCardStore", 20161121000000l);

        ApiManager.i().queryCardStore(this, syncStartTime, new SubscriberAdapter<RespWrapper<List<CardStore>>>() {
            @Override
            public void onNext(RespWrapper<List<CardStore>> o) {
                super.onNext(o);
                if (C.http.RESULT_CODE_SUCCESS == o.code) {
                    List<CardStore> cardStoreList = o.decode(new TypeToken<List<CardStore>>() {
                    }.getType());

                    if (cardStoreList != null) {
                        if (isNeedUpdateLocalData) {
                            String json = App.i().getGson().toJson(cardStoreList);
                            File fJsonData = new File(getExternalCacheDir(), "cache_card_store_list_2_" + System.currentTimeMillis() + ".json");
                            boolean result = Utils.saveFile(json, fJsonData.getAbsolutePath());
                            int count = cardStoreList != null ? cardStoreList.size() : -1;
                            Utils.loge("CardSearchActivity syncData result[" + count + "] : " + (result ? "completed" : "failure"));
                        }

                        CardStoreDao cardStoreDao = App.i().getCommonDBSession().getCardStoreDao();
                        cardStoreDao.insertOrReplaceInTx(cardStoreList);

                        CardGradeDao cardGradeDao = App.i().getCommonDBSession().getCardGradeDao();
                        for (CardStore cs : cardStoreList) {
                            List<CardGrade> cardGradeList = cs.getCardsGradeList();
                            if (cardGradeList != null) {
                                cardGradeDao.insertOrReplaceInTx(cardGradeList);
                            }
                        }
                    }

                    prepareDataByDBQuery();
                }
            }
        }.errorToast(false));
    }

    @Override
    public void onMenuClick(TitleLayout lTitle, String flag) {
        Utils.onMobEvent(this, "clickCustomOfList");
        Intent intent = new Intent(this, CardAddByCodeActivity.class);
        CardStore other = new CardStore();
        other.setBusinessId(C.settings.BUSINESS_OTHER_ID);
        intent.putExtra("extra_card_store", other);
        startActivity(intent);
    }

    @Override
    @OnClick({R.id.i_clear, R.id.e_search, R.id.t_close})
    public void onClick(View v) {
        if (v == iClear) {
            eSearch.setText("");
            iClear.setVisibility(View.GONE);
        } else if (v == eSearch) {
            Utils.onMobEvent(CardSearchActivity.this, "clickSearchBusiness");
        } else if (v == tClose) {
            eSearch.setText("");
            iClear.setVisibility(View.GONE);
            eSearch.clearFocus();
            listSearch.setVisibility(View.GONE);
            listSticky.setVisibility(View.VISIBLE);
            tEmpty.setVisibility(View.GONE);
            tClose.setVisibility(View.GONE);
            Utils.hideSoftInputFromWindowAlways(this);
        } else if (v == lAddOther) {
            Utils.onMobEvent(this, "clickCustomOfList");
            Intent intent = new Intent(this, CardAddByCodeActivity.class);
            CardStore other = new CardStore();
            other.setBusinessId(C.settings.BUSINESS_OTHER_ID);
            intent.putExtra("extra_card_store", other);
            startActivity(intent);
        }
    }

    @Override
    @OnFocusChange({R.id.e_search})
    public void onFocusChange(View v, boolean hasFocus) {
        if (v == eSearch) {
            if (hasFocus) {
                listSearch.setVisibility(View.VISIBLE);
                listSticky.setVisibility(View.GONE);
                tClose.setVisibility(View.VISIBLE);
            } else if (!hasFocus && TextUtils.isEmpty(eSearch.getText())) {
                listSearch.setVisibility(View.GONE);
                listSticky.setVisibility(View.VISIBLE);
                tEmpty.setVisibility(View.GONE);
                tClose.setVisibility(View.GONE);
            }
        }
    }

    private static class CardStoreAdapter extends BaseAdapter implements StickyListHeadersAdapter, SectionIndexer {
        private class Element {
            long zoneId;
            String zoneName;
            CardStore content;
            final int type = 1;
        }

        private final List<Element> elements = new ArrayList<>();

        public void setData(List<CardStore> dataList) {
            elements.clear();
            if (dataList != null && dataList.size() > 0) {
                List<Element> normalList = new ArrayList<>();
                List<Element> hotList = new ArrayList<>();

                String hotTitle = "热门品牌";

                for (CardStore cs : dataList) {
                    Element eItem = new Element();
                    eItem.zoneId = cs.getSort().hashCode();
                    eItem.zoneName = cs.getSort();
                    eItem.content = cs;
                    normalList.add(eItem);

                    if (cs.getIfHot() != null && CardStore.STATUS_HOT == cs.getIfHot()) {
                        CardStore csHot = copyEntity(cs);
                        csHot.setSort("热");
                        Element eItemHot = new Element();
                        eItemHot.zoneId = 0;
                        eItemHot.zoneName = hotTitle;
                        eItemHot.content = csHot;
                        hotList.add(eItemHot);
                    }
                }
                elements.addAll(hotList);
                elements.addAll(normalList);
            }
            notifyDataSetChanged();
        }

        @Override
        public int getCount() {
            return elements.size();
        }

        @Override
        public Object getItem(int position) {
            return elements.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }


        class ViewHolderItem implements View.OnClickListener {
            CardStore cs;
            ImageView iIcon;
            TextView tName;

            @Override
            public void onClick(View v) {
                Utils.onMobEvent(v.getContext(), "clickBusinessOfList");
                Intent intent = new Intent(v.getContext(), CardAddByCodeActivity.class);
                intent.putExtra("extra_card_store", cs);
                v.getContext().startActivity(intent);
            }
        }

        class ViewHeadHolder {
            TextView tGroupTitle;
        }

        @Override
        public int getItemViewType(int position) {
            return elements.get(position).type;
        }

        @Override
        public int getViewTypeCount() {
            return 1;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolderItem vhItem;
            if (convertView == null) {
                convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_card_search_content, parent, false);
            }
            vhItem = (ViewHolderItem) convertView.getTag();
            if (vhItem == null) {
                convertView.setTag(vhItem = new ViewHolderItem());
                vhItem.tName = (TextView) convertView.findViewById(R.id.t_name);
                vhItem.tName.getPaint().setFakeBoldText(true);
                convertView.setOnClickListener(vhItem);
                vhItem.iIcon = (ImageView) convertView.findViewById(R.id.i_icon);
            }

            vhItem.cs = elements.get(position).content;
            Glide.with(convertView.getContext())
                    .load(vhItem.cs.getBusinessIcon())
                    .placeholder(R.mipmap.ic_launcher)
                    .centerCrop()
                    .bitmapTransform(App.i().getCropCircleTransformation())
                    .into(vhItem.iIcon);
            vhItem.tName.setText(vhItem.cs.getBusinessName());
            return convertView;
        }

        @Override
        public View getHeaderView(int position, View convertView, ViewGroup parent) {
            ViewHeadHolder viewHolder;
            if (convertView == null) {
                convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_card_search_head, parent, false);
                convertView.setTag(viewHolder = new ViewHeadHolder());
                viewHolder.tGroupTitle = (TextView) convertView.findViewById(R.id.t_group_title);
            } else {
                viewHolder = (ViewHeadHolder) convertView.getTag();
            }
            String headerText = elements.get(position).zoneName;
            viewHolder.tGroupTitle.setText(headerText);
            return convertView;
        }

        @Override
        public long getHeaderId(int position) {
            return elements.get(position).zoneId;
        }

        @Override
        public Object[] getSections() {
            return null;
        }

        @Override
        public int getPositionForSection(int sectionIndex) {
            for (int i = 0; i < getCount(); i++) {
                String sortStr = elements.get(i).content.getSort();
                char firstChar = sortStr.toUpperCase().charAt(0);
                if (firstChar == sectionIndex) {
                    return i;
                }
            }
            return -1;
        }

        @Override
        public int getSectionForPosition(int position) {
            return elements.get(position).content.getSort().charAt(0);
        }

        CardStore copyEntity(CardStore c) {
            CardStore value = new CardStore();
            value.setBusinessId(c.getBusinessId());
            value.setBusinessName(c.getBusinessName());
            value.setBusinessIcon(c.getBusinessIcon());
            value.setSort(c.getSort());
            value.setBusinessRemark(c.getBusinessRemark());
            value.setIfHot(c.getIfHot());
            value.setBarcodeFormat(c.getBarcodeFormat());
            value.setBarcodeStatus(c.getBarcodeStatus());
            value.setSearchKeys(c.getSearchKeys());
            value.setBackColor(c.getBackColor());
            value.setRegionId(c.getRegionId());
            value.setUseCount(c.getUseCount());
            return value;
        }
    }

    private static class CardStoreAfterSearchedAdapter extends BaseAdapter {
        final List<CardStore> elements = new ArrayList<>();

        public void setData(List<CardStore> dataList) {
            elements.clear();
            if (dataList != null && dataList.size() > 0) {
                elements.addAll(dataList);
            }
            notifyDataSetChanged();
        }

        @Override
        public int getCount() {
            return elements.size();
        }

        @Override
        public Object getItem(int position) {
            return elements.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }


        class ViewHolderItem implements View.OnClickListener {
            CardStore cs;
            ImageView iIcon;
            TextView tName;

            @Override
            public void onClick(final View v) {
                Utils.onMobEvent(v.getContext(), "clickBusinessOfList");
                Intent intent = new Intent(v.getContext(), CardAddByCodeActivity.class);
                intent.putExtra("extra_card_store", cs);
                v.getContext().startActivity(intent);
            }
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolderItem vhItem;
            if (convertView == null) {
                convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_card_search_content, parent, false);
            }
            vhItem = (ViewHolderItem) convertView.getTag();
            if (vhItem == null) {
                convertView.setTag(vhItem = new ViewHolderItem());
                convertView.setOnClickListener(vhItem);
                vhItem.tName = (TextView) convertView.findViewById(R.id.t_name);
                vhItem.tName.getPaint().setFakeBoldText(true);
                vhItem.iIcon = (ImageView) convertView.findViewById(R.id.i_icon);
            }
            vhItem.cs = elements.get(position);

            if (!TextUtils.isEmpty(vhItem.cs.getBusinessIcon())) {
                Glide.with(convertView.getContext()).load(vhItem.cs.getBusinessIcon())
                        .placeholder(R.mipmap.ic_launcher)
                        .centerCrop()
                        .bitmapTransform(App.i().getCropCircleTransformation())
                        .into(vhItem.iIcon);
            }

            vhItem.tName.setText(vhItem.cs.getBusinessName());
            return convertView;
        }
    }



}
